package com.weds.data_sync.util.xxl_component;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.weds.data_sync.util.xxl_component.pojo.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @Description xxl操作工具类
 * @Author lihw
 * @Date 2024/1/18 16:39
 */
public class XxlTemplate implements InitializingBean {

    private XxlProperties xxlProperties;

    private RestTemplate restTemplate;

    private HttpHeaders httpHeaders;

    public XxlTemplate(XxlProperties xxlProperties, RestTemplate restTemplate) {
        this.xxlProperties = xxlProperties;
        this.restTemplate = restTemplate;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("xxlTemplate init success");
    }

    /**
     * 生成调用秘钥
     *
     * @return
     */
    public String generateRpcToken() {
        AES aes = SecureUtil.aes(xxlProperties.getSecret().getBytes(StandardCharsets.UTF_8));
        return aes.encryptBase64(xxlProperties.getToken());
    }

    public HttpHeaders getHeader() {
        if (Objects.isNull(httpHeaders)) {
            HttpHeaders headers = new HttpHeaders();
            headers.set(xxlProperties.getTOKEN_KEY(), generateRpcToken());
            httpHeaders = headers;
            return headers;
        } else {
            return httpHeaders;
        }

    }


    /**
     * 查询执行器列表
     *
     * @param start   页数,从0开始
     * @param length  每页条数
     * @param appname 执行器名称【唯一】
     * @param title   执行器备注(标题)
     * @return
     */
    @org.jetbrains.annotations.Nullable
    public Object queryExecutorList(Integer start, Integer length, String appname, String title) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getQueryExecutorListApi();
        ExecutorQueryDto queryDto = ExecutorQueryDto.builder()
                .start(start)
                .length(length)
                .appname(appname)
                .title(title)
                .build();

        HttpEntity<ExecutorQueryDto> request = new HttpEntity<>(queryDto, getHeader());

        ResponseEntity<Object> response = restTemplate.postForEntity(url, request, Object.class);

        return response.getBody();
    }

    /**
     * 增加执行器
     *
     * @param appname     执行器名称   【唯一】
     * @param title       执行器备注（标题）
     * @param addressType 执行器类型： 执行器地址类型：0=自动注册、1=手动录入
     * @param addressList 执行器地址：执行器地址列表，多地址逗号分隔(手动录入)
     * @return
     */
    @Nullable
    public Object addExecutorItem(String appname, String title, int addressType, @Nullable String addressList) {

        String url = xxlProperties.getAdminAddresses() + xxlProperties.getAddExecutorApi();
        ExecutorItemDto entity = ExecutorItemDto.builder()
                .appname(appname)
                .title(title)
                .addressType(addressType)
                .addressList(addressList)
                .build();
        HttpEntity<ExecutorItemDto> request = new HttpEntity<>(entity, getHeader());

        ResponseEntity<Object> response = restTemplate.postForEntity(url, request, Object.class);
        return response.getBody();
    }

    /**
     * 增加执行器
     *
     * @param id          执行器id
     * @param appname     执行器名称   【唯一】
     * @param title       执行器备注（标题）
     * @param addressType 执行器类型： 执行器地址类型：0=自动注册、1=手动录入
     * @param addressList 执行器地址：执行器地址列表，多地址逗号分隔(手动录入)
     * @return
     */
    @Nullable
    public Object updateExecutorItem(int id, String appname, String title, int addressType, @Nullable String addressList) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getUpdateExecutorApi();
        ExecutorItemDto entity = ExecutorItemDto.builder()
                .id(id)
                .appname(appname)
                .title(title)
                .addressType(addressType)
                .addressList(addressList)
                .build();
        HttpEntity<ExecutorItemDto> request = new HttpEntity<>(entity, getHeader());

        ResponseEntity<Object> response = restTemplate.postForEntity(url, request, Object.class);
        return response.getBody();
    }

    /**
     * 删除执行器
     *
     * @param id
     * @return
     */
    @Nullable
    public Object deleteExecutorItem(int id) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getRemoveExecutorApi() + "?id=" + id;
        HttpEntity<Void> request = new HttpEntity<>(getHeader());

        ResponseEntity<Object> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                request,
                Object.class
        );
        return response.getBody();
    }

    /**
     * 查询任务列表
     *
     * @param taskQueryDto start           页数，从0页开始
     *                     length          每页条数
     *                     jobGroup        执行器id
     *                     triggerStatus   调度状态：0 停止 1 运行
     *                     jobDesc         任务描述
     *                     executorHandler 执行器任务handler
     *                     author          坐着
     * @return
     */
    @Nullable
    public Object queryTaskList(TaskQueryDto taskQueryDto) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getQueryTaskListApi();

        HttpEntity<TaskQueryDto> request = new HttpEntity<>(taskQueryDto, getHeader());

        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, request, Object.class);
        return response.getBody();
    }

    /**
     * 新增任务
     *
     * @param taskDto 任务对象
     * @return
     */
    @Nullable
    public Object addTaskItem(TaskDto taskDto) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getAddTaskApi();

        HttpEntity<TaskDto> request = new HttpEntity<>(taskDto, getHeader());

        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, request, Object.class);
        return response.getBody();
    }

    /**
     * 修改任务
     *
     * @param taskDto 任务对象
     * @return
     */
    @Nullable
    public Object updateTaskItem(TaskDto taskDto) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getUpdateTaskApi();
        HttpEntity<TaskDto> request = new HttpEntity<>(taskDto, getHeader());
        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, request, Object.class);
        return response.getBody();
    }

    /**
     * 删除任务
     *
     * @param id 任务id
     * @return
     */
    @Nullable
    public Object removeTaskItem(Integer id) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getRemoveTaskApi() + "?id=" + id;
        HttpEntity<Void> request = new HttpEntity<>(getHeader());
        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.GET, request, Object.class);
        return response.getBody();
    }


    /**
     * 停止任务
     *
     * @param id 任务id
     * @return
     */
    @Nullable
    public Object stopTaskItem(Integer id) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getStopTaskApi() + "?id=" + id;
        HttpEntity<Void> request = new HttpEntity<>(getHeader());
        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.GET, request, Object.class);
        return response.getBody();
    }

    /**
     * 启动任务
     *
     * @param id 任务id
     * @return
     */
    @Nullable
    public Object startTaskItem(Integer id) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getStartTaskApi() + "?id=" + id;
        HttpEntity<Void> request = new HttpEntity<>(getHeader());
        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.GET, request, Object.class);
        return response.getBody();
    }

    /**
     * 触发一次任务
     *
     * @param triggerQueryDto id                任务id
     *                        executorParam     执行参数
     *                        addressList       执行器地址。多个用逗号拼接
     * @return
     */
    @Nullable
    public Object triggerTaskId(TriggerQueryDto triggerQueryDto) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getTriggerTaskApi();
        HttpEntity<TriggerQueryDto> request = new HttpEntity<>(triggerQueryDto, getHeader());
        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, request, Object.class);
        return response.getBody();
    }

    /**
     * 获取任务下次执行时间
     * @param nextTriggerDto
     * @return
     */
    @Nullable
    public Object nextTriggerTime(NextTriggerDto nextTriggerDto) {
        String url = xxlProperties.getAdminAddresses() + xxlProperties.getNextTriggerTimeTaskApi();
        HttpEntity<NextTriggerDto> request = new HttpEntity<>(nextTriggerDto, getHeader());
        ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, request, Object.class);
        return response.getBody();
    }

}
